package qj.tool.string;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import qj.util.ArrayUtil4;
import qj.util.StringUtil4;

public class Name {
	public static final int CAMEL 		= 0;
	public static final int CAMEL2 		= 1;

	public static final int UPPERCASED 	= 2;
    /**
     * le_anh_quan
     */
	public static final int LOWEREDCASED= 3;
    /**
     * Le Anh Quan
     */
	public static final int SEPARATE 	= 4;
	
	private String[] parts;
	
	private Name(String[] parts) {
		this.parts = parts;
	}

	private static final Pattern PTN_CAMEL = Pattern.compile("[a-z]+|[A-Z][a-z]+|[A-Z]+|[0-9]+|_");
	private static final Pattern PTN_UPPERCASED = Pattern.compile("[A-Z]+|[0-9]+");
	private static final Pattern PTN_LOWEREDCASED = Pattern.compile("[a-z]+|[0-9]+");
	private static final Pattern PTN_SEPARATE = PTN_CAMEL;
	
	@SuppressWarnings("unchecked")
	public static Name compile(String name, int type) {
		ArrayList list = new ArrayList();
		Matcher matcher;
		switch (type) {
		case CAMEL:
		case CAMEL2:
		case SEPARATE:
			matcher = PTN_CAMEL.matcher(name);
			break;
		case UPPERCASED:
			matcher = PTN_UPPERCASED.matcher(name);
			break;
		case LOWEREDCASED:
			matcher = PTN_LOWEREDCASED.matcher(name);
			break;
		default:
			throw new IllegalArgumentException("Unknow name format type");
		}

		while (matcher.find())
			list.add(matcher.group(0).toLowerCase());
		return new Name((String[]) list.toArray(new String[list.size()]));
	}

	/**
	 * leAnhQuan
	 * @return
	 */
	public String getCamelFormat() {

		StringBuffer sb = new StringBuffer();
		sb.append(parts[0]);
		for (int i = 1; i < parts.length; i++) {
			sb.append(StringUtil4.upperCaseFirstChar(parts[i]));
		}
		
		return sb.toString();
	}
	
	/**
	 * Le Anh Quan
	 * @return
	 */
	public String getSeparateFormat() {

		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < parts.length; i++) {
			if (i > 0) {
				sb.append(" ");
			}
			sb.append(StringUtil4.upperCaseFirstChar(parts[i]));
		}
		
		return sb.toString();
	}
	
	/**
	 * LE_ANH_QUAN
	 * @return
	 */
	public String getUppercasedFormat() {

		StringBuffer sb = new StringBuffer();
		if (ArrayUtil4.isNotEmpty(parts)) {
			sb.append(parts[0].toUpperCase());
			for (int i = 1; i < parts.length; i++) {
				sb.append("_").append(parts[i].toUpperCase());
			}
		}
		return sb.toString();
		
	}

	/**
	 * le_anh_quan
	 * @return
	 */
	public String getLowercasedFormat() {

		StringBuffer sb = new StringBuffer();
		sb.append(parts[0]);
		for (int i = 1; i < parts.length; i++) {
			sb.append("_").append(parts[i]);
		}
		
		return sb.toString();
		
	}

	/**
	 * LeAnhQuan
	 * @return
	 */
	public String getCamel2Format() {

		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < parts.length; i++) {
			sb.append(StringUtil4.upperCaseFirstChar(parts[i]));
		}
		
		return sb.toString();
	}

	public String getName(int type) {
		switch (type) {
		case CAMEL:
			return getCamelFormat();
		case UPPERCASED:
			return getUppercasedFormat();
		case LOWEREDCASED:
			return getLowercasedFormat();
		case CAMEL2:
			return getCamel2Format();
		case SEPARATE:
			return getSeparateFormat();
		}
		return null;
	}
	
	public static String convert(String fromStr, int fromType, int toType) {
		return Name.compile(fromStr, fromType).getName(toType);
	}
	
	public static void main(String[] args) {
		System.out.println(convert("PDR_ID", UPPERCASED, CAMEL));
		System.out.println(convert("PERSON_ID", UPPERCASED, CAMEL));
		System.out.println(convert("UPDATE_ALLOWED", UPPERCASED, CAMEL));
		System.out.println(convert("PDR_START_DATE", UPPERCASED, CAMEL));
		System.out.println(convert("PDR_END_DATE", UPPERCASED, CAMEL));
		System.out.println(convert("PDR_TYPE", UPPERCASED, CAMEL));
		System.out.println(convert("POSITION_NAME", UPPERCASED, CAMEL));
		System.out.println(convert("PDR_STATUS", UPPERCASED, CAMEL));
		System.out.println(convert("LAST_UPDATE_DATE", UPPERCASED, CAMEL));
		System.out.println(convert("LAST_UPDATED_BY", UPPERCASED, CAMEL));
		System.out.println(convert("CAREER_ASPIRATIONS", UPPERCASED, CAMEL));
		System.out.println(convert("CAREER_ASP_UPDATEABLE", UPPERCASED, CAMEL));
		System.out.println(convert("DEV_NEEDS_DELETE", UPPERCASED, CAMEL));
		System.out.println(convert("DEV_NEEDS_INSERT", UPPERCASED, CAMEL));
		System.out.println(convert("DEV_NEEDS_UPDATEABLE", UPPERCASED, CAMEL));
		System.out.println(convert("SIGN_OFF_ENABLED", UPPERCASED, CAMEL));
	}
}
